{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6RLNvyXlDhG2"
      },
      "source": [
        "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pinecone-io/examples/blob/master/integrations/groq/groq-llama-3-rag.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/pinecone-io/examples/blob/master/integrations/groq/groq-llama-3-rag.ipynb)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FZ6sj8gPDhG4"
      },
      "source": [
        "# RAG with Groq and Llama 3"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "h8o5TRVfDhG4"
      },
      "source": [
        "To begin, we setup our prerequisite libraries."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "id": "thtg9njP4bOh"
      },
      "outputs": [],
      "source": [
        "!pip install -qU \\\n",
        "    datasets==2.14.5 \\\n",
        "    groq==0.8.0 \\\n",
        "    \"semantic-router[local]==0.0.45\" \\\n",
        "    pinecone-client==4.1.0"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VReBq2IeDhG5"
      },
      "source": [
        "## Data Preparation"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "eY3OglQm4bOj"
      },
      "source": [
        "We start by downloading a dataset that we will encode and store. The dataset [`jamescalam/ai-arxiv2-semantic-chunks`](https://huggingface.co/datasets/jamescalam/ai-arxiv2-semantic-chunks) contains scraped data from many popular ArXiv papers centred around LLMs and GenAI."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "pQAVgquj4bOk",
        "outputId": "20e50564-752c-41f2-a622-81ff7065f8e4"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:89: UserWarning: \n",
            "The secret `HF_TOKEN` does not exist in your Colab secrets.\n",
            "To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.\n",
            "You will be able to reuse this secret in all of your notebooks.\n",
            "Please note that authentication is recommended but still optional to access public models or datasets.\n",
            "  warnings.warn(\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "Dataset({\n",
              "    features: ['id', 'title', 'content', 'prechunk_id', 'postchunk_id', 'arxiv_id', 'references'],\n",
              "    num_rows: 10000\n",
              "})"
            ]
          },
          "metadata": {},
          "execution_count": 2
        }
      ],
      "source": [
        "from datasets import load_dataset\n",
        "\n",
        "data = load_dataset(\n",
        "    \"jamescalam/ai-arxiv2-semantic-chunks\",\n",
        "    split=\"train[:10000]\"\n",
        ")\n",
        "data"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wrC-XHrTDhG6"
      },
      "source": [
        "We have 200K chunks, where each chunk is roughly the length of 1-2 paragraphs in length. Here is an example of a single record:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "RQg8wiUQ4bOk",
        "outputId": "68000734-f92b-4e0b-ed5c-157b5fe88b4e"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'id': '2401.04088#0',\n",
              " 'title': 'Mixtral of Experts',\n",
              " 'content': '4 2 0 2 n a J 8 ] G L . s c [ 1 v 8 8 0 4 0 . 1 0 4 2 : v i X r a # Mixtral of Experts Albert Q. Jiang, Alexandre Sablayrolles, Antoine Roux, Arthur Mensch, Blanche Savary, Chris Bamford, Devendra Singh Chaplot, Diego de las Casas, Emma Bou Hanna, Florian Bressand, Gianna Lengyel, Guillaume Bour, Guillaume Lample, LÃ©lio Renard Lavaud, Lucile Saulnier, Marie-Anne Lachaux, Pierre Stock, Sandeep Subramanian, Sophia Yang, Szymon Antoniak, Teven Le Scao, ThÃ©ophile Gervet, Thibaut Lavril, Thomas Wang, TimothÃ©e Lacroix, William El Sayed Abstract We introduce Mixtral 8x7B, a Sparse Mixture of Experts (SMoE) language model. Mixtral has the same architecture as Mistral 7B, with the difference that each layer is composed of 8 feedforward blocks (i.e. experts). For every token, at each layer, a router network selects two experts to process the current state and combine their outputs. Even though each token only sees two experts, the selected experts can be different at each timestep. As a result, each token has access to 47B parameters, but only uses 13B active parameters during inference. Mixtral was trained with a context size of 32k tokens and it outperforms or matches Llama 2 70B and GPT-3.5 across all evaluated benchmarks. In particular, Mixtral vastly outperforms Llama 2 70B on mathematics, code generation, and multilingual benchmarks. We also provide a model fine- tuned to follow instructions, Mixtral 8x7B â Instruct, that surpasses GPT-3.5 Turbo, Claude-2.1, Gemini Pro, and Llama 2 70B â chat model on human bench- marks. Both the base and instruct models are released under the Apache 2.0 license.',\n",
              " 'prechunk_id': '',\n",
              " 'postchunk_id': '2401.04088#1',\n",
              " 'arxiv_id': '2401.04088',\n",
              " 'references': ['1905.07830']}"
            ]
          },
          "metadata": {},
          "execution_count": 3
        }
      ],
      "source": [
        "data[0]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "euFtJiIz4bOk"
      },
      "source": [
        "Format the data into the format we need, this will contain `id`, `text` (which we will embed), and `metadata`."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "u-svyAMw4bOl",
        "outputId": "5e699da6-0761-4a22-a28c-03fa0f6ef9de"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "Dataset({\n",
              "    features: ['id', 'metadata'],\n",
              "    num_rows: 10000\n",
              "})"
            ]
          },
          "metadata": {},
          "execution_count": 4
        }
      ],
      "source": [
        "data = data.map(lambda x: {\n",
        "    \"id\": x[\"id\"],\n",
        "    \"metadata\": {\n",
        "        \"title\": x[\"title\"],\n",
        "        \"content\": x[\"content\"],\n",
        "    }\n",
        "})\n",
        "# drop uneeded columns\n",
        "data = data.remove_columns([\n",
        "    \"title\", \"content\", \"prechunk_id\",\n",
        "    \"postchunk_id\", \"arxiv_id\", \"references\"\n",
        "])\n",
        "data"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MYzwm_q_4bOl"
      },
      "source": [
        "We need to define an embedding model to create our embedding vectors for retrieval, for that we will be using a variation of the `e5-base` model with a longer context length of `4k` tokens. Ideally we should be running this on GPU for optimal runtimes."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "nVjJ6gGd4bOl"
      },
      "outputs": [],
      "source": [
        "from semantic_router.encoders import HuggingFaceEncoder\n",
        "\n",
        "encoder = HuggingFaceEncoder(name=\"dwzhu/e5-base-4k\")"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "We can check whether our `encoder` will use `cpu` or a `cuda` GPU (where available)."
      ],
      "metadata": {
        "id": "SE9B1lG1GS04"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "encoder.device"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        },
        "id": "Q2dGUK_DGTHB",
        "outputId": "5580bfa8-72b7-477c-c959-00bd833b3834"
      },
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "'cuda'"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            }
          },
          "metadata": {},
          "execution_count": 6
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "We can create embeddings now like so:"
      ],
      "metadata": {
        "id": "pqJWCYzsP5DD"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "embeds = encoder([\"this is a test\"])"
      ],
      "metadata": {
        "id": "C8KdMnKlP7bG"
      },
      "execution_count": 7,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "We can view the dimensionality of our returned embeddings, which we'll need soon when initializing our vector index:"
      ],
      "metadata": {
        "id": "8zdYGmkTQS8e"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "dims = len(embeds[0])\n",
        "dims"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "X1UygwjvQYlh",
        "outputId": "d1eeb65b-1b16-4017-a92a-8c1b5a01b870"
      },
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "768"
            ]
          },
          "metadata": {},
          "execution_count": 8
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ndAuMyYC4bOm"
      },
      "source": [
        "Now we create our vector DB to store our vectors. For this we need to get a [free Pinecone API key](https://app.pinecone.io) — the API key can be found in the \"API Keys\" button found in the left navbar of the Pinecone dashboard."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "id": "ThmEhCcI4bOm"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "import getpass\n",
        "from pinecone import Pinecone\n",
        "\n",
        "# initialize connection to pinecone (get API key at app.pinecone.io)\n",
        "api_key = os.getenv(\"PINECONE_API_KEY\") or getpass.getpass(\"Enter your Pinecone API key: \")\n",
        "\n",
        "# configure client\n",
        "pc = Pinecone(api_key=api_key)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YtEcZE5AfQHW"
      },
      "source": [
        "Now we setup our index specification, this allows us to define the cloud provider and region where we want to deploy our index. You can find a list of all [available providers and regions here](https://docs.pinecone.io/docs/projects)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "id": "vVmlAytrfeUJ"
      },
      "outputs": [],
      "source": [
        "from pinecone import ServerlessSpec\n",
        "\n",
        "spec = ServerlessSpec(\n",
        "    cloud=\"aws\", region=\"us-west-2\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-nu2KHWG4bOm"
      },
      "source": [
        "Creating an index, we set `dimension` equal to the dimensionality of our encoder (`384`), and use a `metric` also compatible with the model (this can be `cosine`). We also pass our `spec` to index initialization."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "D4E9wrzx4bOm",
        "outputId": "4630fe3d-aa3d-4b44-d401-f03435f396a8"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'dimension': 768,\n",
              " 'index_fullness': 0.0,\n",
              " 'namespaces': {},\n",
              " 'total_vector_count': 0}"
            ]
          },
          "metadata": {},
          "execution_count": 11
        }
      ],
      "source": [
        "import time\n",
        "\n",
        "index_name = \"groq-llama-3-rag\"\n",
        "existing_indexes = [\n",
        "    index_info[\"name\"] for index_info in pc.list_indexes()\n",
        "]\n",
        "\n",
        "# check if index already exists (it shouldn't if this is first time)\n",
        "if index_name not in existing_indexes:\n",
        "    # if does not exist, create index\n",
        "    pc.create_index(\n",
        "        index_name,\n",
        "        dimension=dims,\n",
        "        metric='cosine',\n",
        "        spec=spec\n",
        "    )\n",
        "    # wait for index to be initialized\n",
        "    while not pc.describe_index(index_name).status['ready']:\n",
        "        time.sleep(1)\n",
        "\n",
        "# connect to index\n",
        "index = pc.Index(index_name)\n",
        "time.sleep(1)\n",
        "# view index stats\n",
        "index.describe_index_stats()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ZI76rcTi4bOm"
      },
      "source": [
        "We can see the index is currently empty with a `total_vector_count` of `0`. We can begin populating it with our embeddings."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 49,
          "referenced_widgets": [
            "f7ecc1ba349c4684ab74589d76d1c8bd",
            "887604f171f0485c9d183a4742033c61",
            "13dcb21cd4a94a8ebb84e03d7b4bb4c9",
            "8431c77a08414f6d9390836824e952ee",
            "c6f584ae1b4d4bdcb8a06310f481ed6c",
            "7fa1947dfa304f769b1aaeddbc68680a",
            "ce362059d93f4c5aaecf6cdce80e4ae5",
            "67d69eeb76d04341b53c692bcb3f45d5",
            "ed4cecb304b24ac2bbe3c0ed38f3d5f0",
            "b45a832ba57748d680c5230bb8f7f976",
            "392134a2a1f949ea8197c8471c02036f"
          ]
        },
        "id": "a2xvoFt04bOn",
        "outputId": "a699ecea-69f6-4371-b889-a6aec4aa40a3"
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "  0%|          | 0/79 [00:00<?, ?it/s]"
            ],
            "application/vnd.jupyter.widget-view+json": {
              "version_major": 2,
              "version_minor": 0,
              "model_id": "f7ecc1ba349c4684ab74589d76d1c8bd"
            }
          },
          "metadata": {}
        }
      ],
      "source": [
        "from tqdm.auto import tqdm\n",
        "\n",
        "batch_size = 128  # how many embeddings we create and insert at once\n",
        "\n",
        "for i in tqdm(range(0, len(data), batch_size)):\n",
        "    # find end of batch\n",
        "    i_end = min(len(data), i+batch_size)\n",
        "    # create batch\n",
        "    batch = data[i:i_end]\n",
        "    # create embeddings\n",
        "    chunks = [f'{x[\"title\"]}: {x[\"content\"]}' for x in batch[\"metadata\"]]\n",
        "    embeds = encoder(chunks)\n",
        "    assert len(embeds) == (i_end-i)\n",
        "    to_upsert = list(zip(batch[\"id\"], embeds, batch[\"metadata\"]))\n",
        "    # upsert to Pinecone\n",
        "    index.upsert(vectors=to_upsert)"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "batch[\"metadata\"]"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "lGQXG51RJCUi",
        "outputId": "0a28a72f-ef02-495e-ba6c-d4992450f988"
      },
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[{'content': '4 . So the answer is 9Ï 4 . Are there variables in the solution? the form of \"1. variable is defined as...\". If so, please list the definition of variable in The underlined parts are the type of question, the question itself and the steps in its solution, respectively. The output from the LLM is: Yes. There are variables in the solution. x + yi, where xxx and yyy are real numbers. x + yi 1. zzz is defined as a complex number of the form x + yi',\n",
              "  'title': 'SelfCheck: Using LLMs to Zero-Shot Check Their Own Step-by-Step Reasoning'},\n",
              " {'content': 'The bold part is then saved to form a part of the input in the regeneration stage. Target extraction To get a brief and clear target of the current step, the input to the LLM is: The following is a part of the solution to the problem: Let S be the set of complex numbers z such that the real part of 1 6 . This set forms a curve. Find the area of the 12 region inside the curve. (Step 0) Let z = x + yi be a complex number, where x and y are real numbers. (Step 5) Completing the square, we obtain (a â 3)? +y= Q. 3)? +y= Q. 2 . . . : 2 What specific action does the step \"Completing the square, we obtain (a â 3) take? Please give a brief answer using a single sentence and do not copy the steps. 2 2 +y= 4 .\" The underlined parts are the question and reasoning steps before the current one, including the current one. The output of the LLM is: The step completes the square to rewrite the equation in standard form of a circle. The whole sentence is saved and forms the most important part of the input in the regeneration stage. Information Collection To get sentences in the question and previous steps in the solution that are directly related to the current step, the input to the LLM is: This is a math question: Question: Let S be the set of complex numbers z such that the real part of 1 6 . This set forms a curve. Find the area of the region inside the curve.',\n",
              "  'title': 'SelfCheck: Using LLMs to Zero-Shot Check Their Own Step-by-Step Reasoning'},\n",
              " {'content': 'The following is information extracted from the question: Information 0: Let S be the set of complex numbers z such that the real part of 1 1 6 . Information 1: This set forms a curve. Information 2: Find the area of the region inside the curve. The following is the first a few steps in a solution to the problem: Step 0: Let z = x + yi be a complex number, where x and y are real numbers. ... Step 4: Cross-multiplying and rearranging, we get the equation 6x = x2 + y2. Which previous steps or information does the next step \"Completing the square, we obtain (x â 3) _ p= on\" directly follow from? _ p= 4 .\" directly follow from? 2 The underlined information (contents after Information X:) is simply a list of sentences in the question. The underlined steps are reasoning steps before (not including) the current one in the solution. The output from the LLM is: The next step \"Completing the square, we obtain (x â 3)? +y? = 2.\" directly follows from Step 4. Then we use regular expression to extract the information and step id from LLMâ s output. Some steps may only rely on information from the question while others may only use results from previous steps. Step regeneration In this stage, we instruct the LLM to achieve the extracted target with only collected information with the following prompt: We are in a process of solving a math problem.',\n",
              "  'title': 'SelfCheck: Using LLMs to Zero-Shot Check Their Own Step-by-Step Reasoning'},\n",
              " {'content': 'Variables are defined as: 1. z is defined as a complex number of the form x + yi, where x and y are real numbers. The following are some previous steps: Step 0: Cross-multiplying and rearranging, we get the equation 6x = x2 + y2. 13 The target for next step is: The step completes the square to rewrite the equation in standard form of a circle. Please try to achieve the target with the information from previous steps. The underlined parts are the type of question, variable definition (if any), collected information from the question (if any), collected previous steps (if any) and the extracted target. Please notice that the current step does not directly rely on any information from the question, we removed the corresponding block from the input. The output from the LLM is:',\n",
              "  'title': 'SelfCheck: Using LLMs to Zero-Shot Check Their Own Step-by-Step Reasoning'},\n",
              " {'content': 'To rewrite the equation in standard form of a circle, we need to complete the square for both xxx and yyy. 6x = x2 + y2 Starting from the given equation: 6x = x2 + y2 6x = x2 + y2. (6/2)2 = 9 We add and subtract (6/2)2 = 9 (6/2)2 = 9 on the right-hand side: 6x + 9 â 9 = x2 + y2 + 9 â 9 6x + 9 â 9 = x2 + y2 + 9 â 9. 6x + 9 â 9 = x2 + y2 + 9 â 9 (x â 3)2 + y2 = 9 Simplifying: (x â 3)2 + y2 = 9 (x â 3)2 + y2 = 9. This is now in the standard form of a circle with (3, 0) and radius 333. (3, 0) center (3, 0)',\n",
              "  'title': 'SelfCheck: Using LLMs to Zero-Shot Check Their Own Step-by-Step Reasoning'},\n",
              " {'content': 'Then we can directly compare the regenerated step with the original one in the next stage. Result comparison The input to the LLM is: The following are 2 solutions to a math problem: Solution 1: To rewrite the equation in standard form of a circle, we need to complete the square for both x and y. Starting from the given equation: 6x = x2 + y2. We add and subtract (6/2)2 = 9 on the right-hand side: 6x + 9 â 9 = x2 + y2 + 9 â 9. Simplifying: (x â 3)2 + y2 = 9. This is now in the standard form of a circle with center (3, 0) and radius 3. Solution 2: Completing the square, we obtain (2 â 2 a)? +y= 8. Compare the key points from both solutions step by step and then check whether Solution 1 \"supports\", \"contradicts\" or \"is not directly related to\" the conclusion in Solution 2. Pay special attention to difference in numbers. The underlined parts are simply the problem type, the regenerated step and the original step. The output is: In both solutions, the goal is to rewrite the given equation in standard form of a circle. However, in Solution 1, the completion of the square results in the center of the circle being (3, 0) and a radius of 3. In Solution 2, the completion of the square results in the center of the circle being (3/2, 0) and a radius of 3/2. Therefore, Solution 1 contradicts the conclusion in Solution 2 as the centers and radii of the circles are different.',\n",
              "  'title': 'SelfCheck: Using LLMs to Zero-Shot Check Their Own Step-by-Step Reasoning'},\n",
              " {'content': 'If the word â supportâ or â contradictâ appears in the last line of the output, SelfCheck outputs a step score 1 or -1. Otherwise, SelfCheck outputs 0 meaning that two steps are not related. # APPENDIX B EXAMPLAR FOR ONE-SHOT ERROR CHECKING The following example from Ling et al. (2023) is used to perform one-shot error checking. Here is some information: â 1. Alice gets 2 apples. 2. Alice gets twice as many oranges as bananas. 3. Original price per apple: $2',\n",
              "  'title': 'SelfCheck: Using LLMs to Zero-Shot Check Their Own Step-by-Step Reasoning'},\n",
              " {'content': '14 Discount: 50% Price per apple after discount: $2 * (1 - 0.50) = $2 * 0.50 = $1\" Based on the given information, here is a reasoning process: \"Calculate Aliceâ s cost of the 5 apples after a 50% discount. Price per apple after discount: $1 Apples be eaten: 3 Oranges be eaten: 6 Total apples: 5 Total oranges: x Total bananas: 2x Aliceâ s total number of fruits: 5 + x + 2x = 5 + 4x Aliceâ s total cost of 5 apples: $1 * (5 - 3) = $2â Double-check the reasoning process, letâ s analyze its correctness, and end with \"yes\" or \"no\". Answer: Letâ s think step by step.',\n",
              "  'title': 'SelfCheck: Using LLMs to Zero-Shot Check Their Own Step-by-Step Reasoning'},\n",
              " {'content': 'Grounding check Purpose: Find references for numbers in the reasoning process sequentially Rule: Any ungrounded number makes the check fails \"x\" is a variable, we do not care about variables. \"y\" is a variable, we do not care about variables. \"5\" is a quantity from the given information that represents the number of apples. \"50%\" is a quantity from the given information that represents the discount. \"$1\" is a quantity from the given information that represents the price per apple after the discount. \"3\" is a quantity not from the given information, it is ungrounded. \"6\" is a quantity not from the given information, it is ungrounded. \"$2\" is a quantity from the given information that represents the original price per apple.',\n",
              "  'title': 'SelfCheck: Using LLMs to Zero-Shot Check Their Own Step-by-Step Reasoning'},\n",
              " {'content': 'Result: Based on the check, there are ungrounded numbers, so the grounding check fails. Reasoning check: Purpose: Check whether the reasoning logic correctly answers the question Rule: Any logic error makes the check fails To calculate the total cost of apples after a 50% discount, we should multiply the number of apples by the discounted price. But to answer the question, we do not need to calculate the total number of fruit Alice gets. Result: Based on the check, there are some logic mistakes, so the reasoning check fails. Calculation check: Purpose: Check whether the calculation process is consistent Rule: Any inconsistent calculation makes the check fails calculation1: equation: $1 * (5 - 3), answer: $2 (5 - 3) = 2 $1 * 2 = $2 is consistent with the answer, so the calculation is correct. calculation2: equation: 5 + x + 2x, answer: 5 + 4x x + 2x = 3x 5 + 3x is inconsistent with the answer, so the calculation is incorrect. Result: Based on the check, the calculation process is inconsistent, so the calculation check fails. Check results: Ground check fails, Reasoning check fails, Calculation check fails. Rule: Any failed check makes the reasoning incorrect. So the answer is \"no\".',\n",
              "  'title': 'SelfCheck: Using LLMs to Zero-Shot Check Their Own Step-by-Step Reasoning'},\n",
              " {'content': '15',\n",
              "  'title': 'SelfCheck: Using LLMs to Zero-Shot Check Their Own Step-by-Step Reasoning'},\n",
              " {'content': '3 2 0 2 v o N 6 ] I A . s c [ 5 v 2 5 3 0 0 . 8 0 3 2 : v i X r a Preprint # METAGPT: META PROGRAMMING FOR A MULTI-AGENT COLLABORATIVE FRAMEWORK Sirui Hong1â , Mingchen Zhuge2â , Jonathan Chen1, Xiawu Zheng3, Yuheng Cheng4, Ceyao Zhang4, Jinlin Wang1, Zili Wang, Steven Ka Shing Yau5, Zijuan Lin4, Liyang Zhou6, Chenyu Ran1, Lingfeng Xiao1,7, Chenglin Wu1â , J Â¨urgen Schmidhuber2,8 1DeepWisdom, 2AI Initiative, King Abdullah University of Science and Technology, 3Xiamen University, 5Nanjing University, 7University of California, Berkeley, # ABSTRACT Remarkable progress has been made on automated problem solving through so- cieties of agents based on large language models (LLMs). Existing LLM-based multi-agent systems can already solve simple dialogue tasks. Solutions to more complex tasks, however, are complicated through logic inconsistencies due to cascading hallucinations caused by naively chaining LLMs. Here we introduce MetaGPT, an innovative meta-programming framework incorporating efficient human workflows into LLM-based multi-agent collaborations. MetaGPT en- codes Standardized Operating Procedures (SOPs) into prompt sequences for more streamlined workflows, thus allowing agents with human-like domain expertise to verify intermediate results and reduce errors. MetaGPT utilizes an assembly line paradigm to assign diverse roles to various agents, efficiently breaking down complex tasks into subtasks involving many agents working together. On col- laborative software engineering benchmarks, MetaGPT generates more coherent solutions than previous chat-based multi-agent systems. Our project can be found at https://github.com/geekan/MetaGPT',\n",
              "  'title': 'MetaGPT: Meta Programming for A Multi-Agent Collaborative Framework'},\n",
              " {'content': '1 # INTRODUCTION Autonomous agents utilizing Large Language Models (LLMs) offer promising opportunities to en- hance and replicate human workflows. In real-world applications, however, existing systems (Park et al., 2023; Zhuge et al., 2023; Cai et al., 2023; Wang et al., 2023c; Li et al., 2023; Du et al., 2023; Liang et al., 2023; Hao et al., 2023) tend to oversimplify the complexities. They struggle to achieve effective, coherent, and accurate problem-solving processes, particularly when there is a need for meaningful collaborative interaction (Zhang et al., 2023; Dong et al., 2023; Zhou et al., 2023; Qian et al., 2023). Through extensive collaborative practice, humans have developed widely accepted Standardized Operating Procedures (SOPs) across various domains (Belbin, 2012; Manifesto, 2001; DeMarco & Lister, 2013). These SOPs play a critical role in supporting task decomposition and effective coor- dination. Furthermore, SOPs outline the responsibilities of each team member, while establishing standards for intermediate outputs. Well-defined SOPs improve the consistent and accurate exe- cution of tasks that align with defined roles and quality standards (Belbin, 2012; Manifesto, 2001; DeMarco & Lister, 2013; Wooldridge & Jennings, 1998). For instance, in a software company, Product Managers analyze competition and user needs to create Product Requirements Documents (PRDs) using a standardized structure, to guide the developmental process. Inspired by such ideas, we design a promising GPT-based Meta-Programming framework called MetaGPT that significantly benefits from SOPs. Unlike other works (Li et al., 2023; Qian et al., 2023), MetaGPT requires agents to generate structured outputs, such as high-quality requirements',\n",
              "  'title': 'MetaGPT: Meta Programming for A Multi-Agent Collaborative Framework'},\n",
              " {'content': 'â These authors contributed equally to this work. â Chenglin Wu (alexanderwu@fuzhi.ai) is the corresponding author, affiliated with DeepWisdom. 1 Preprint MetaGPT Agents Collaboration with Developing SOP 1/5 | | One-line requirement Define Write a classic and simple Flappy Bird game. 2/5 : Design Boss makes acceptance: check and payment Planning Requirement Analysis Architectural Design Meta Programming System Design 1 3/5 % | Plan&Code Pretty good ! I can %, 1 directly use the %, * a| Â¢ interface and %, . 1 â _ keyboard to play oe, 7 4/5 Flappy Bird. % â Testin; 7 Test ms bd QA Engineer W â N am Â°R . a4 cn 4 5/5] Figure 1:',\n",
              "  'title': 'MetaGPT: Meta Programming for A Multi-Agent Collaborative Framework'},\n",
              " {'content': 'The software development SOPs between MetaGPT and real-world human teams. In software engineering, SOPs promote collaboration among various roles. MetaGPT showcases its ability to decompose complex tasks into specific actionable procedures assigned to various roles (e.g., Product Manager, Architect, Engineer, etc.). documents, design artifacts, flowcharts, and interface specifications. The use of intermediate struc- tured outputs significantly increases the success rate of target code generation. More graphically, in a company simulated by MetaGPT, all employees follow a strict and streamlined workflow, and all their handovers must comply with certain established standards. This reduces the risk of hallucina- tions caused by idle chatter between LLMs, particularly in role-playing frameworks, like: â',\n",
              "  'title': 'MetaGPT: Meta Programming for A Multi-Agent Collaborative Framework'},\n",
              " {'content': 'Hi, hello and how are you?â â Alice (Product Manager); â Great! Have you had lunch?â â Bob (Architect). Benefiting from SOPs, MetaGPT offers a promising approach to meta-programming. In this context, we adopt meta-programming1 as â programming to programâ , in contrast to the broader fields of meta learning and â learning to learnâ (Schmidhuber, 1987; 1993a; Hochreiter et al., 2001; Schmidhuber, 2006; Finn et al., 2017). This notion of meta-programming also encompasses earlier efforts like CodeBERT (Feng et al., 2020) and recent projects such as CodeLlama (Rozi`ere et al., 2023) and WizardCoder (Luo et al., 2023). However, MetaGPT stands out as a unique solution that allows for efficient meta- programming through a well-organized group of specialized agents. Each agent has a specific role and expertise, following some established standards. This allows for automatic requirement analysis, system design, code generation, modification, execution, and debugging during runtime, highlight- ing how agent-based techniques can enhance meta-programming. To validate the design of MetaGPT, we use publicly available HumanEval (Chen et al., 2021a) and MBPP (Austin et al., 2021) for evaluations. Notably, in code generation benchmarks, MetaGPT achieves a new state-of-the-art (SoTA) with 85.9% and 87.7% in Pass@1. When compared to other popular frameworks for creating complex software projects, such as AutoGPT (Torantulino et al., 2023), LangChain (Chase, 2022), AgentVerse (Chen et al., 2023), and ChatDev (Qian et al., 2023). MetaGPT also stands out in handling higher levels of software complexity and offering extensive functionality. Remarkably, in our experimental evaluations, MetaGPT achieves a 100% task com- pletion rate, demonstrating the robustness and efficiency (time and token costs) of our design. We summarize our contributions as follows:',\n",
              "  'title': 'MetaGPT: Meta Programming for A Multi-Agent Collaborative Framework'}]"
            ]
          },
          "metadata": {},
          "execution_count": 13
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oyFZKhUa4bOn"
      },
      "source": [
        "Now let's test retrieval!"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "id": "6pUo5EQK4bOn"
      },
      "outputs": [],
      "source": [
        "def get_docs(query: str, top_k: int) -> list[str]:\n",
        "    # encode query\n",
        "    xq = encoder([query])\n",
        "    # search pinecone index\n",
        "    res = index.query(vector=xq, top_k=top_k, include_metadata=True)\n",
        "    # get doc text\n",
        "    docs = [x[\"metadata\"]['content'] for x in res[\"matches\"]]\n",
        "    return docs"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "C3FASr-04bOn",
        "outputId": "45734407-6c1a-4d75-feb7-cd6ac293f9e9"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Code llama: Open foundation models for code. arXiv preprint arXiv:2308.12950, 2023. William Saunders, Catherine Yeh, Jeff Wu, Steven Bills, Long Ouyang, Jonathan Ward, and Jan Leike. Self-critiquing models for assisting human evaluators. CoRR, abs/2206.05802, 2022. doi: 10.48550/arXiv.2206.05802. URL https://doi.org/10.48550/arXiv.2206.05802.\n",
            "---\n",
            "Chinese-oriented Models (Continue Pretraining) F F T T F F T T Llama1 BLOOMZ-7B1-mt Llama1 Llama1 Llama2 Llama2 Llama2 Llama2 7B, 13B 7B 7B, 13B, 33B 13B 7B 7B 7B 13B 2k 1k 8k 2k 4k 4k 4k 4k 5w 200w 200w, 300w, 430w 110w 1000w â 120w 100w English-oriented Models Llama2-chat (Touvron et al. 2023) Vicuna-V1.3 (Zheng et al. 2023) Vicuna-V1.5 (Zheng et al. 2023) WizardLM (Xu et al. 2023b) LongChat-V1 (Li* et al. 2023) LongChat-V1.5 (Li* et al. 2023) OpenChat-V3.2 (Wang et al. 2023a) GPT-3.5-turbo GPT-4 Llama2 Llama1 Llama2 Llama1 Llama1 Llama2 Llama2 - - 7B, 13B, 70B 7B, 13B, 33B 7B, 13B 13B 7B, 13B 7B 13B - - N/A N/A N/A N/A N/A N/A N/A N/A N/A 4k 2k 16k 2k 16k 32k 4k 16k 16k 10w 12w 12w 25w 8w, 2w â 0.6w â â\n",
            "---\n",
            "MMLU: MMLU includes 57 multiple-choice tasks covering subjects spanning STEM to social science [17]. The tasks differ significantly in complexity, with many STEM-oriented questions demanding domain-specific professional knowledge and intricate reasoning to be solved. TruthfulQA: TruthfulQA contains 817 factual questions to detect model falsehoods caused by naively mimicking human language patterns [27]. The solutions to these questions are closely associated with English Wikipedia sources. The task probes a modelâ s factual knowledge and resistance to popular misconceptions. Table 3: Performance of FLM-101B and baselines including LLAMA series and GLM-130B. In order to visually compare the performance and cost, we estimate the floating-point opera- tions (zetta = 1021) of the training process. Model Cost (zettaFLOPs) Average ARC HellaSwag MMLU TruthfulQA LLAMA-2 (13B) LLAMA-2 (7B) LLAMA (13B) LLAMA (7B) GLM-130B 201.37 106.60 94.81 49.54 210.80 (Â±28.77) (Â±15.23) (Â±13.54) (Â±7.08) 58.66 54.32 56.08 49.72 48.11 28.22 43.94 59.39 53.07 56.23 51.02 42.15 39.76 82.13 78.59 80.93 77.82 67.91 66.23 55.77 46.87 47.67 35.71 42.59 28.30â 37.38 38.76 39.48 34.33 39.80 41.47 # FLM-101B â 44.50 for a knowledge-enhanced eFLM-16B (Section 2.2, 4.2). Table 3 details the performance of FLM-101B and strong baselines, including LLAMA series and GLM-130B. Because GPT-3 is closed-source, we could not get the probability values for a fair comparison. As a result, we cannot list GPT-3 here.\n",
            "---\n",
            "LLaMA LLaMA (Touvron et al., 2023a) is an auto-regressive, decoder-only large language model based on the Transformer architecture. The model is characterized by its billions of param- eters, pre-trained on a vast amount of web data. Being uni-directional means that the modelâ s at- tention mechanism only considers the preceding elements in the input sequence when making pre- dictions. Specifically, given an input sequence x = [t1, t2, ..., tnâ 1], the model computes the prob- ability of the next token tn based solely on the preceding tokens. The prediction process can be mathematically represented as P (tn|t1, ..., tnâ 1), where P denotes the probability and tn represents the next element in the sequence.\n",
            "---\n",
            "One notable development in this area is the emergence of open-source LLMs, specifically LLaMA (Touvron et al., 2023a) and LLAMA 2 (Touvron et al., 2023b), which have been recognized as the most powerful open-source language models ever created. This has led to a surge of activity in the open-source community (Wolf et al., 2019), with a series of large language models being developed collaboratively to build upon this progress (Mosaic ML, 2023; Almazrouei et al., 2023; ChatGLM2 Team, 2023; Yang et al., 2023; InternLM Team, 2023).\n"
          ]
        }
      ],
      "source": [
        "query = \"can you tell me about the Llama LLMs?\"\n",
        "docs = get_docs(query, top_k=5)\n",
        "print(\"\\n---\\n\".join(docs))"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Our retrieval component works, now let's try feeding this into a Llama 3 70B model hosted by Groq to produce an answer."
      ],
      "metadata": {
        "id": "OSOMoBcFf0ma"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from groq import Groq\n",
        "\n",
        "os.environ[\"GROQ_API_KEY\"] = os.getenv(\"GROQ_API_KEY\") or getpass.getpass(\"Enter your Groq API key: \")\n",
        "\n",
        "groq_client = Groq(api_key=os.environ[\"GROQ_API_KEY\"])"
      ],
      "metadata": {
        "id": "F9reHp5jN13y"
      },
      "execution_count": 16,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "Now we can generate responses using Llama 3, we'll wrap this logic into a help function called `generate`:"
      ],
      "metadata": {
        "id": "ilW47QJtXceq"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def generate(query: str, docs: list[str]):\n",
        "    system_message = (\n",
        "        \"You are a helpful assistant that answers questions about AI using the \"\n",
        "        \"context provided below.\\n\\n\"\n",
        "        \"CONTEXT:\\n\"\n",
        "        \"\\n---\\n\".join(docs)\n",
        "    )\n",
        "    messages = [\n",
        "        {\"role\": \"system\", \"content\": system_message},\n",
        "        {\"role\": \"user\", \"content\": query}\n",
        "    ]\n",
        "    # generate response\n",
        "    chat_response = groq_client.chat.completions.create(\n",
        "        model=\"llama3-70b-8192\",\n",
        "        messages=messages\n",
        "    )\n",
        "    return chat_response.choices[0].message.content"
      ],
      "metadata": {
        "id": "JERWhNXNf8cR"
      },
      "execution_count": 17,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "out = generate(query=query, docs=docs)\n",
        "print(out)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "krsfvRdiiMnX",
        "outputId": "09e5c647-601d-4503-f0f2-2afd54a74669"
      },
      "execution_count": 18,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "The LLaMA LLMs refer to a series of large language models developed by researchers, specifically LLaMA and LLAMA 2. These models are notable for being open-source, which has led to a surge of activity in the open-source community.\n",
            "\n",
            "LLaMA is an auto-regressive, decoder-only large language model based on the Transformer architecture. It's characterized by its billions of parameters and pre-training on a vast amount of web data. Being uni-directional, the model's attention mechanism only considers the preceding elements in the input sequence when making predictions.\n",
            "\n",
            "From the comparison tables, we can see that LLaMA and LLAMA 2 come in different sizes, such as 7B, 13B, and 33B, indicating the number of parameters in each model. These models have been tested on various tasks, including MMLU, TruthfulQA, ARC, and HellaSwag, and have shown competitive performance compared to other strong baselines.\n",
            "\n",
            "The emergence of open-source LLMs like LLaMA and LLAMA 2 has enabled the open-source community to build upon this progress, leading to the development of new large language models through collaborative efforts.\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "u8OfJFwq4bOo"
      },
      "source": [
        "Don't forget to delete your index when you're done to save resources!"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "metadata": {
        "id": "LQiU0IDl4bOo"
      },
      "outputs": [],
      "source": [
        "pc.delete_index(index_name)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0gThAy0k4bOo"
      },
      "source": [
        "---"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": [],
      "gpuType": "T4"
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.9.12"
    },
    "orig_nbformat": 4,
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "f7ecc1ba349c4684ab74589d76d1c8bd": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_887604f171f0485c9d183a4742033c61",
              "IPY_MODEL_13dcb21cd4a94a8ebb84e03d7b4bb4c9",
              "IPY_MODEL_8431c77a08414f6d9390836824e952ee"
            ],
            "layout": "IPY_MODEL_c6f584ae1b4d4bdcb8a06310f481ed6c"
          }
        },
        "887604f171f0485c9d183a4742033c61": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_7fa1947dfa304f769b1aaeddbc68680a",
            "placeholder": "​",
            "style": "IPY_MODEL_ce362059d93f4c5aaecf6cdce80e4ae5",
            "value": "100%"
          }
        },
        "13dcb21cd4a94a8ebb84e03d7b4bb4c9": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_67d69eeb76d04341b53c692bcb3f45d5",
            "max": 79,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_ed4cecb304b24ac2bbe3c0ed38f3d5f0",
            "value": 79
          }
        },
        "8431c77a08414f6d9390836824e952ee": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_b45a832ba57748d680c5230bb8f7f976",
            "placeholder": "​",
            "style": "IPY_MODEL_392134a2a1f949ea8197c8471c02036f",
            "value": " 79/79 [06:32&lt;00:00,  4.16s/it]"
          }
        },
        "c6f584ae1b4d4bdcb8a06310f481ed6c": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "7fa1947dfa304f769b1aaeddbc68680a": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "ce362059d93f4c5aaecf6cdce80e4ae5": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "67d69eeb76d04341b53c692bcb3f45d5": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "ed4cecb304b24ac2bbe3c0ed38f3d5f0": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "b45a832ba57748d680c5230bb8f7f976": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "392134a2a1f949ea8197c8471c02036f": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        }
      }
    },
    "accelerator": "GPU"
  },
  "nbformat": 4,
  "nbformat_minor": 0
}